package com.itheima.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.Category;
import com.itheima.bean.Dish;
import com.itheima.bean.Setmeal;
import com.itheima.bean.SetmealDish;
import com.itheima.common.pageParm;
import com.itheima.dao.DishDao;
import com.itheima.dao.SetmealDao;
import com.itheima.dao.SetmealDishDao;
import com.itheima.dto.SetmealDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.SetmealDishService;
import com.itheima.service.SetmealService;
import com.itheima.service.dishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SetmealServiceImpl implements SetmealService {

    @Resource
    private SetmealDao setmealDao;


    @Resource
    private SetmealDishService setmealDishService;



    @Resource
    private dishService dishservice;

    @Lazy
    @Resource
    private CategoryService categoryService;

    @Autowired
    private DishDao dishDao;


    @Override
    public List<Setmeal> findByCategoryId(Long categoryId, Integer status) {
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();

        lqw.eq(Setmeal::getCategoryId, categoryId);


        return setmealDao.selectList(lqw);


    }

    @Override
    public int add(SetmealDto setmealDto) {

        //添加到套餐表
        int row = setmealDao.insert(setmealDto);


        if (row > 0) {
            //添加到套餐菜品表
            List<SetmealDish> setmealDishList = setmealDto.getSetmealDishes();

            int row2 = 0;
            //遍历每一道菜
            for (SetmealDish setmealDish : setmealDishList) {

                setmealDish.setSetmealId(setmealDto.getId());


                row2 += setmealDishService.add(setmealDish);
            }
            return row2 == setmealDishList.size() ? 1 : 0;
        }
        return row;
    }


    @Override
    public IPage<SetmealDto> findPage(pageParm pageParm) {

        Page<Setmeal> p = new Page<>(pageParm.getPage(), pageParm.getPageSize());


        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();

        lqw.like(pageParm.getName() != null, Setmeal::getName, pageParm.getName());


        Page<Setmeal> setmealPage = setmealDao.selectPage(p, lqw);

        List<SetmealDto> setmealDtoList = setmealPage.getRecords().stream().map((setmeal) -> {


            //找到每个菜品的分类
            Category category = categoryService.findById(setmeal.getCategoryId());

            //去查询套餐里面有什么菜品
            List<SetmealDish> setmealDishList = setmealDishService.findBySetmealId(setmeal.getId());
            //
            //for (SetmealDish setmealDish : setmealDishList) {
            //
            //    Dish dish = dishservice.findByDishId(setmealDish.getDishId());
            //
            //    setmealDish.setImage(dish.getImage());
            //
            //}


            List<SetmealDish> setmealDishList1=setmealDishList.stream().map(setmealDish -> {

                Dish dish = dishservice.findByDishId(setmealDish.getDishId());

                setmealDish.setImage(dish.getImage());

                return setmealDish;
            }).collect(Collectors.toList());


            //构建setmealDto然后封装数据
            SetmealDto setmealDto = new SetmealDto();

            //封装分类数据
            setmealDto.setCategoryName(category.getName());
            //封装菜品数据

            setmealDto.setSetmealDishes(setmealDishList1);

            //拷贝原来的setmeal数据到setmealDto

            BeanUtils.copyProperties(setmeal, setmealDto);


            return setmealDto;

        }).collect(Collectors.toList());


        IPage<SetmealDto> dtoIPage = new Page<>();

        dtoIPage.setRecords(setmealDtoList);

        dtoIPage.setTotal(setmealPage.getTotal());

        return dtoIPage;

    }

    @Override
    public int update(SetmealDto setmealDto) {

        //先更新套餐表 按照id来更新
        int row = setmealDao.updateById(setmealDto);

        //再更新菜品表
        if (row > 0) {
            //2.1先把这个套餐的菜品数据删除掉
            int row2 = setmealDishService.deletBysetmealId(setmealDto.getId());
            //2.2再把这个套餐的菜品数据添加进来
            List<SetmealDish> setmealDishList = setmealDto.getSetmealDishes();
            //2.2.1 先判断页面有没有给过来菜品数据，如果有就添加，没有就不添加

            if (setmealDishList != null && setmealDishList.size() > 0) {

                int row3 = 0;

                for (SetmealDish setmealDish : setmealDishList) {

                    setmealDish.setSetmealId(setmealDto.getId());
                    setmealDish.setImage(setmealDto.getImage());

                    row3 += setmealDishService.add(setmealDish);
                }

                return row3 == setmealDishList.size() ? 1 : 0;
            }

        }
        return row;
    }

    @Override
    public int delete(List<Long> ids) {

        //先通过条件查询 看看哪个套餐是起售状态！
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();

        lqw.in(Setmeal::getId, ids);

        lqw.eq(Setmeal::getStatus, 1);//staus为1就是起售，可以放个固定值！

        //查询到了有几个符合条件的影响行数。如果有就禁止删除，
        int total = setmealDao.selectCount(lqw);

        if (total > 0) {
            throw new CustomException("有套餐处于启售状态，禁止删除！");
        }


        //返回删除套餐的影响行数
        int row = setmealDao.deleteBatchIds(ids);


        for (Long id : ids) {

            setmealDishService.deletBysetmealId(id);
        }


        return row;

    }

    /**
     * 批量起售和停售
     *
     * @param ids
     * @param status
     * @return
     */
    @Override
    public int updateStatus(List<Long> ids, Integer status) {
        //先查询套餐含有的菜品,判断能不能更新 如果菜品有起售就不能停售,如果菜品有停售就不能启售
        int count = ids.stream().map(id ->
                setmealDishService.findBySetmealId(id)).mapToInt(list -> {

            for (SetmealDish setmealDish : list) {

                Dish dish = dishDao.selectById(setmealDish.getDishId());

                if (!status.equals(dish.getStatus())) {//不能操作
                    if (status.equals(1))
                    throw new CustomException("该套餐还有菜品在停售，不能更新");
                    else
                        throw new CustomException("该套餐还有菜品在启售，不能更新");
                }
            }
            return 1;
        }).sum();

        if (count == ids.size()) {//可以操作
            for (Long id : ids) {

                count = 0;

                Setmeal setmeal = setmealDao.selectById(id);

                setmeal.setStatus(status);

                count += setmealDao.updateById(setmeal);

            }
            return count == ids.size() ? 1 : 0;
        }
        return 0;
    }

}
